package com.lantosec.hmrp.modules.form.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lantosec.hmrp.core.kit.Result;
import com.lantosec.hmrp.core.util.BeanUtils;
import com.lantosec.hmrp.modules.form.entity.FormColumns;
import com.lantosec.hmrp.modules.form.entity.FormTable;
import com.lantosec.hmrp.modules.form.enumeration.ColoumnTypeEnum;
import com.lantosec.hmrp.modules.form.mapper.FormColumnsMapper;
import com.lantosec.hmrp.modules.form.service.IBindColumnValueService;
import com.lantosec.hmrp.modules.form.service.IFormColumnsService;
import com.lantosec.hmrp.modules.form.service.IFormTableService;
import com.lantosec.hmrp.modules.form.vo.FormColumnsVO;
import com.lantosec.hmrp.modules.form.vo.UpdateCommentVO;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;

/**
 * <p>
 * 自定义表单列定义 服务实现类
 * </p>
 *
 * @author AutoCode
 * @since 2020-04-15
 */
@Service
@Primary
@Log4j2
public class FormColumnsServiceImpl extends ServiceImpl<FormColumnsMapper, FormColumns> implements IFormColumnsService {

    @Autowired
    IBindColumnValueService bindColumnValueService;
    @Autowired
    IFormTableService formTableService;

    @Override
    public List<FormColumnsVO> queryByTableInfo(String tableSchema, String tableName, String tableType) {
        List<FormColumnsVO> list = baseMapper.queryByTableInfo(tableSchema, tableName);
        list.forEach(item -> {
            item.setColumnType(ColoumnTypeEnum.BASE_COLUMN.getType());
            if("PRI".equals(item.getColumnKey())){
                item.setPrimaryKey(true);
            }
            else if("MUL".equals(item.getColumnKey())){
                item.setForeignKey(true);
            }
            if("auto_increment".equals(item.getExtra())){
                //item.setColumnType(true);
            }
        });
        return list;
    }

    @Override
    public List<FormColumns> queryByTableId(String tableId, Boolean isToCamelCase) {
        if (StringUtils.isBlank(tableId)) {
            return null;
        }
        List<FormColumns> list = baseMapper.selectList(new QueryWrapper<FormColumns>()
                .eq(String.valueOf(FormColumns.ColName.table_id), tableId)
                .orderByAsc(String.valueOf(FormColumns.ColName.ordinal_position))
        );
        if(isToCamelCase) {
            //下划线，转换为驼峰式
            list.forEach(item -> {
                item.setColumnName(com.lantosec.hmrp.core.util.StringUtils.underlineToCamelCase(item.getColumnName()));
            });
        }
        return list;
    }

    @Override
    public Result<Boolean> synchronizeColumn(String tableId) {
        if (StringUtils.isBlank(tableId)) return Result.fail("参数错误");

        // 查询表信息
        FormTable formTable = formTableService.getBaseMapper().selectById(tableId);
        if (Objects.isNull(formTable))  return Result.fail("查询表信息失败");

        String tableName = formTable.getTableName();
        // 查询数据库所有的表字段
        List<FormColumnsVO> list = baseMapper.queryByTableInfo(formTable.getTableSchema(), formTable.getTableName());
        List<FormColumns> entityList = BeanUtils.VO2Entity(list);
        // 查询form_columns表该表所有的字段
        List<FormColumns> formColumnsList = baseMapper.selectList(new QueryWrapper<FormColumns>().eq(String.valueOf(FormColumns.ColName.table_id), tableId));
        // 需要同步新增的列集合
        List<FormColumns> insertList = new ArrayList<>();
        Date now = new Date();
        // 如果在form_columns表没有的字段则新增
        entityList.forEach(item -> {
            long count = formColumnsList.stream().filter(a -> a.getColumnName().equals(item.getColumnName())).count();
            if(count==0) {
                item.setColumnType(ColoumnTypeEnum.BASE_COLUMN.getType());
                item.setTableId(tableId);
                item.setCreateDate(now);
                insertList.add(item);
            }
        });

        // 批量保存
        boolean flag = super.saveBatch(insertList);
        return Result.ok(flag);
    }

    @Override
    public Result<String> saveColumn(FormColumns entity) {
        if (!isExist(entity)) {
            return Result.fail("表单字段名称已经存在");
        }
        // 只能添加扩展字段
        entity.setColumnType(ColoumnTypeEnum.EXT_COLUMN.getType());
        entity.setCreateDate(new Date());

        boolean flag = super.save(entity);
        if(!flag) {
            return Result.fail("保存失败");
        }
        return Result.ok(entity.getColumnId());
    }

    @Override
    public Result<Void> updateColumn(FormColumns entity) {
        if (!isExist(entity)) {
            return Result.fail("表单字段名称已经存在");
        }
        boolean flag = super.updateById(entity);
        if(!flag) {
            return Result.fail("保存失败");
        }
        return Result.ok();
    }

    @Override
    public Result<Void> updateColumnComment(UpdateCommentVO updateCommentVO) {
        String columnId = updateCommentVO.getColumnId();
        String columnComment = updateCommentVO.getColumnComment();
        if (StringUtils.isBlank(columnId) || StringUtils.isBlank(columnComment)) {
            return Result.fail("参数不存在");
        }
        FormColumns updateModel = new FormColumns();
        updateModel.setColumnId(columnId);
        updateModel.setColumnComment(columnComment);
        boolean flag = super.updateById(updateModel);
        if (!flag) {
            return Result.fail("修改失败");
        }
        return Result.ok();
    }

    /**
     * 同一表不能有相同的列名
     *
     * @param entity
     * @return
     */
    private boolean isExist(FormColumns entity) {
        Integer count = baseMapper.selectCount(new QueryWrapper<FormColumns>()
                .notIn(StringUtils.isNotBlank(entity.getColumnId()), String.valueOf(FormColumns.ColName.column_id), entity.getColumnId())
                .eq(String.valueOf(FormColumns.ColName.table_id), entity.getTableId())
                .eq(String.valueOf(FormColumns.ColName.column_name), entity.getColumnName()));
        if (count > 0) {
            return false;
        }
        return true;
    }

    @Override
    public boolean removeById(Serializable id) {
        // 只能删除扩展字段
        FormColumns model = baseMapper.selectById(id);
        if (!Objects.isNull(model) && ColoumnTypeEnum.EXT_COLUMN.getType().equals(model.getColumnType())) {
            return super.removeById(id);
        }
        return false;
    }

    @Override
    public Result<Object> bindColumnValue(String formData) {
        String key = "columnId";
        JSONObject jsonObject = JSON.parseObject(formData);
        if(Objects.isNull(jsonObject)||Objects.isNull(jsonObject.get(key))){
            return Result.fail("缺少参数");
        }

        // 查询字段的列信息
        FormColumns model = baseMapper.selectById(jsonObject.get(key).toString());
        if (Objects.isNull(model)) {
            return Result.fail("没有查询该列的信息");
        }
        Object result = bindColumnValueService.getBindValue(model.getValueType(), model.getValueData(), jsonObject);
        return Result.ok(result);
    }

    @Override
    public List<String> getFieldBySql(String sql) {
        List<String> fieldList = new ArrayList<>();
        List<Map<String, Object>> list = baseMapper.executeSelectSql(sql);
        if (CollectionUtils.isNotEmpty(list)) {
            list.get(0).keySet().forEach(item -> {
                //下划线，转换为驼峰式
                fieldList.add(com.lantosec.hmrp.core.util.StringUtils.underlineToCamelCase(item));
            });
            //fieldList.addAll(list.get(0).keySet());
        }
        return fieldList;
    }
}
